package com.yswee.framework.widget.loading;

import java.util.ArrayList;

import com.yswee.framework.Application;
import com.yswee.framework.R;
import com.yswee.framework.data.BaseArrayData;
import com.yswee.framework.model.BaseListModel;
import com.yswee.framework.model.PageType;
import com.yswee.framework.net.http.Entity;
import com.yswee.framework.widget.adapterview.withmodel.MListView;
import com.yswee.framework.widget.layoutview.ILayoutView;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.Toast;


public abstract class LoadingListView<T> extends LoadingLayout {

	protected PullToRefreshListView mListView;
	
	public LoadingListView(Context context) {
		super(context);
	}
	
	public LoadingListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected View getLayoutView() {
		mListView = new PullToRefreshListView(getContext());
		return mListView;
	}

	@Override
	protected int getLayoutResId() {
		return 0;
	}
	
	@Override
	public void onApplyLoadingData() {
		mListView.getFirstPage();
	}

	protected BaseListModel<T> getMode() {
		return mListView.getModel();
	}

	protected abstract BaseListModel<T> createMode();
	
	protected void initializeListView(MListView<T> listview) {
		
	}
	
	/**
	 * 是否允许加载下一页
	 * @return
	 */
	protected boolean enabledLoadNextPage() {
		return true;
	}
	
	/**
	 * 加载失败的提示语
	 * @return
	 */
	protected int getLoadErrResId() {
		return R.string.get_data_err;
	}
	
	/**
	 * ListView的加载方式
	 * LISTVIEW_TYPE_VIEW  (必须override createLayoutView 方法）
	 * LISTVIEW_TYPE_DATABINDING （必须override getLayoutResId/getLayoutView 方法）
	 * @return
	 */
	protected int getListViewType() {
		return MListView.LISTVIEW_TYPE_VIEW;
	}
	
	protected int getViewTypeCount() {
		return 1;
	}

	protected int getLayoutResId(int position, T t, int itemViewType) {
		return 0;
	}
	
	protected ILayoutView<T> getLayoutView(int position, T t, int itemViewType) {
		return null;
	}
	
	/**
	 * 加载下一页的方式
	 * @return MODE_LOADMORE_BOTTOM 触底加载， MODE_LOADMORE_TOP 触顶加载
	 */
	protected int getLoadMoreMode() {
		return MListView.MODE_LOADMORE_BOTTOM;
	}
	
	/**
	 * 请求第一页数据返回后是否滑动至顶部或底部
	 * @return
	 */
	protected boolean scrollToEdgeOnGetFirstPage() {
		return true;
	}
	
	/**
	 * 请求缓存数据返回后是否滑动至顶部或底部
	 * @return
	 */
	protected boolean scrollToEdgeOnGetCacheData() {
		return false;
	}
	
	/**
	 * 转换数据源
	 * @param array
	 * @return
	 */
	protected ArrayList<T> transferDataSource(ArrayList<T> array) {
		return array;
	}
	
	/**
	 * 获取第一页数据
	 * @param loadCache
	 */
	protected void onGetFirstPage(boolean loadCache) {
		
	}
	
	/**
	 * 获取数据源
	 * @return
	 */
	public ArrayList<T> getDataSource() {
		if(mListView != null) {
			return mListView.getDataSource();
		}
		return null;
	}
	
	/**
	 * 设置数据源
	 * @param data
	 */
	public void setDataSource(ArrayList<T> data) {
		if(mListView != null) {
			mListView.setDataSource(data);
		}
	}
	
	/**
	 * 刷新
	 */
	public void refresh() {
		mListView.getFirstPage();
	}
	
	/**
	 * 通知刷新
	 */
	@Override
	public void notifyDataSetChanged() {
		super.notifyDataSetChanged();
		if (mListView != null) {
			mListView.notifyDataSetChanged();
		}
	}
	
	/**
	 * 增加数据
	 * @param t
	 * @return
	 */
	public boolean addData(T t) {
		return mListView.addData(t);
	}
	
	/**
	 * 增加数据
	 * @param index 索引
	 * @param t 数据
	 * @return
	 */
	public boolean addData(int index, T t) {
		return mListView.addData(index, t);
	}
	
	/**
	 * 移除数据
	 * @param t
	 * @return
	 */
	public boolean removeData(T t) {
		return mListView.removeData(t);
	}
	
	/**
	 * 移除数据
	 * @param index 索引
	 * @return
	 */
	public T removeData(int index) {
		return mListView.removeData(index);
	}
	
	/**
	 * 清空数据
	 * @return
	 */
	public boolean clearData() {
		return mListView.clearData();
	}
	
	protected void onLoadSucc(Entity<BaseArrayData<T>> entity, PageType pagetype) {
		
	}
	
	protected void onLoadBlank(Entity<BaseArrayData<T>> entity, PageType pagetype) {
		
	}
	
	protected void onLoadError(Entity<BaseArrayData<T>> entity, PageType pagetype) {
		
	}
    
    protected boolean enabledSwipeMenu() {
    	return false;
    }
	
	protected boolean enabledSwipeMenu(int position) {
		return true;
	}
	
	protected int getMenuResId(int position, T t, int itemViewType) {
		return 0;
	}
	
	protected ILayoutView<T> getLayoutMenu(int position, T t, int itemViewType) {
		return null;
	}

	protected Interpolator getOpenInterpolator() {
		return null;
	}
	
	protected Interpolator getCloseInterpolator() {
		return null;
	}
	
	protected void smoothCloseMenu() {
    	mListView.smoothCloseMenu();
    }
	
	public class PullToRefreshListView extends com.yswee.framework.widget.adapterview.withmodel.MListView<T> {

		
		public PullToRefreshListView(Context context) {
			super(context);
		}
		
		@Override
		protected int getLoadMoreMode() {
			return LoadingListView.this.getLoadMoreMode();
		}
		
		@Override
		protected boolean enabledLoadNextPage() {
			return LoadingListView.this.enabledLoadNextPage();
		}

		@Override
		protected int getListViewType() {
			return LoadingListView.this.getListViewType();
		}
		
		@Override
		protected int getViewTypeCount() {
			return LoadingListView.this.getViewTypeCount();
		}

		@Override
		protected int getLayoutResId(int position, T t, int itemViewType) {
			return LoadingListView.this.getLayoutResId(position, t, itemViewType);
		}

		@Override
		protected ILayoutView<T> getLayoutView(int position, T t, int itemViewType) {
			return LoadingListView.this.getLayoutView(position, t, itemViewType);
		}

		@Override
		protected void initializeListView() {
			super.initializeListView();
			setDividerHeight(0);
			setHorizontalScrollBarEnabled(false);
			setVerticalScrollBarEnabled(true);
			hideFadingEdge();
			LoadingListView.this.initializeListView(this);
		}

		@Override
		protected BaseListModel<T> createMode() {
			return LoadingListView.this.createMode();
		}
		
		@Override
		protected boolean scrollToEdgeOnGetCacheData() {
			return LoadingListView.this.scrollToEdgeOnGetCacheData();
		}
		
		@Override
		protected boolean scrollToEdgeOnGetFirstPage() {
			return LoadingListView.this.scrollToEdgeOnGetFirstPage();
		}
		
		@Override
		protected void onBeginLoad(boolean isFirstPage) {
			super.onBeginLoad(isFirstPage);
			if(isFirstPage && getAdapterCount() < 1) {
				gotoLoading();
			}
		}
		
		@Override
		public void getFirstPage(boolean loadCache) {
			super.getFirstPage(loadCache);
			LoadingListView.this.onGetFirstPage(loadCache);
		}
		
		@Override
		protected void onLoadSucc(Entity<BaseArrayData<T>> entity, PageType pagetype) {
			super.onLoadSucc(entity, pagetype);
			gotoSuccessful();
			LoadingListView.this.onLoadSucc(entity, pagetype);
		}
		
		@Override
		protected void onLoadBlank(Entity<BaseArrayData<T>> entity, PageType pagetype) {
			superOnLoadBank(entity, pagetype);
			if(pagetype == PageType.FirstPage && getAdapterCount() < 1)
				gotoBlank();
			LoadingListView.this.onLoadBlank(entity, pagetype);
		}
		
		protected void superOnLoadBank(Entity<BaseArrayData<T>> entity, PageType pagetype) {
			super.onLoadBlank(entity, pagetype);
		}
		
		@Override
		protected void onLoadError(Entity<BaseArrayData<T>> entity, PageType pagetype) {
			superOnLoadError(entity, pagetype);
			if(pagetype == PageType.FirstPage && getAdapterCount() < 1) {
				gotoError();
			} else {
				if(entity.getEntityStatus() != Entity.NETINVALID) {
					int resid = LoadingListView.this.getLoadErrResId();
					if(resid > 0) {
						Toast.makeText(Application.get(), resid, Toast.LENGTH_SHORT).show();
					}
				}
			}
			LoadingListView.this.onLoadError(entity, pagetype);
		}
		
		protected void superOnLoadError(Entity<BaseArrayData<T>> entity, PageType pagetype) {
			super.onLoadError(entity, pagetype);
		}
		
		@Override
		public void setDataSource(ArrayList<T> array) {
			super.setDataSource(transferDataSource(array));
		}

		@Override
		protected boolean enabledSwipeMenu(int position) {
			return LoadingListView.this.enabledSwipeMenu(position);
		}

		@Override
		protected int getMenuResId(int position, T t, int itemViewType) {
			return LoadingListView.this.getMenuResId(position, t, itemViewType);
		}

		@Override
		protected ILayoutView<T> getLayoutMenu(int position, T t, int itemViewType) {
			return LoadingListView.this.getLayoutMenu(position, t, itemViewType);
		}

		@Override
		protected Interpolator getOpenInterpolator() {
			return LoadingListView.this.getOpenInterpolator();
		}

		@Override
		protected Interpolator getCloseInterpolator() {
			return LoadingListView.this.getCloseInterpolator();
		}
	}
}
